package os;

import java.util.Enumeration;
import java.util.Hashtable;

import ui.MiniProcessPerspective;

/**
 * Singleton class that keeps track of the processes UI windows. It links the
 * User processes code with their UI windows.
 * 
 * @author Ahmed El-Eryan
 * 
 */
public class MiniUIManager
{

	/**
	 * Singleton instance.
	 */
	private static MiniUIManager instance;

	/**
	 * Singleton get instance.
	 * 
	 * @return Singleton instance.
	 */
	public static MiniUIManager getInstance()
	{
		if (instance == null)
		{
			instance = new MiniUIManager();
		}
		return instance;
	}

	/**
	 * Private constructor to implement the Singleton design pattern.
	 */
	private MiniUIManager()
	{
	}

	/**
	 * Container for the processes' UI windows.
	 */
	private Hashtable<String, MiniProcessPerspective> windows = new Hashtable<String, MiniProcessPerspective>();

	/**
	 * Invoked when a new process is created to open a new window to it.
	 * 
	 * @param pid
	 *            Pid of the created process.
	 * @param title
	 *            Title of the window opened.
	 */
	public void processCreated(String pid, String title)
	{
		MiniProcessPerspective window = new MiniProcessPerspective(pid, title);
		windows.put(pid, window);
		window.open();
	}

	/**
	 * Invoked when a thread requests to display a message on the window (output
	 * request).
	 * 
	 * @param pid
	 *            Pid of the owning process.
	 * @param tid
	 *            Id of the requesting thread.
	 * @param message
	 *            String to be displayed.
	 */
	public void displayMessage(String pid, String tid, String message)
	{
		windows.get(pid).displayMessage(tid, message);
	}

	/**
	 * Invoked when a message is displayed on the window (requested earlier by a
	 * thread).
	 * 
	 * @param pid
	 *            Pid of the owning process.
	 * @param tid
	 *            Id of the thread that requested earlier to display the
	 *            message.
	 */
	public void messageDisplayed(String pid, String tid)
	{
		MiniOS.getInstance().outputRequestCompleted(pid, tid);
	}

	/**
	 * Invoked by a thread to get an input from the user (input request).
	 * 
	 * @param pid
	 *            Pid of the owning process.
	 * @param tid
	 *            Id of the requesting thread.
	 */
	public void enableInput(String pid, String tid)
	{
		windows.get(pid).enableInput(tid);
	}

	/**
	 * Invoked when the user submits input in response to a thread input
	 * request.
	 * 
	 * @param pid
	 *            Pid of the owning process.
	 * @param tid
	 *            Id of the requesting thread.
	 * @param input
	 *            String input by the user.
	 */
	public void inputReceived(String pid, String tid, String input)
	{
		MiniOS.getInstance().inputRequestCompleted(pid, tid, input);
	}

	/**
	 * Invoked when a process terminated to mark its window as terminated.
	 * 
	 * @param pid
	 *            Pid of the terminated process.
	 */
	public void processTerminated(String pid)
	{
		windows.get(pid).processTerminated();
	}

	/**
	 * Called when the OS shuts down to close the windows of all running
	 * processes.
	 */
	public void closeAllWindows()
	{
		Enumeration<MiniProcessPerspective> e = windows.elements();
		while (e.hasMoreElements())
		{
			e.nextElement().close();
		}
	}

	/**
	 * Invoked when the window of a terminated process is closed by the user.
	 * 
	 * @param pid
	 *            Pid of process owning that window.
	 */
	public void windowClosed(String pid)
	{
		windows.remove(pid);
	}

}
